#define SOURCE
#include "userlib.h"

pid_t traced_process = -1;

list<struct Range> writablevma;
list<ResultSet *> results;

int compareaddr(struct Addr *a1, struct Addr *a2)
{
	if(a1->pid<a2->pid) return -1;
	if(a1->pid>a2->pid) return 1;
	if(a1->addr<a2->addr) return -1;
	if(a1->addr>a2->addr) return 1;
	return 0;
}

void die(const char *perrormsg)
{
	perror(perrormsg);
	exit(1);
}

const char* errormsg(int result)
{
	switch(result){
		case 0:	return "Success.";
		case -NO_TRACED_TASK:	return "No traced task.";
		case -CANNOT_WRITE_TO:	return "Dest array is not writtable.";
		case -CANNOT_WRITE_RESULT:	return "Result int * is not writtable.";
		case -TRY_COPY_SELF:	return "Try to copy a vma of oneself.";
		case -TASK_NOT_STOPPED:	return "Traced task is not stopped.";
		case -NO_PRIVILEGE:	return "No privilege to copy memory.";
		case -NO_MM:	return "Traced task is a kernel thread.";
		case -NO_VMA:	return "Source address is not in any vma.";
		case -READ_KERNEL:	return "Try to read kernel address space.";
		case -TASK_NOT_TRACED:	return "Such task is not traced.";
		case -LEN_TOO_LONG:	return "Read length is too long.";
		case -ADDR_NOT_ALIGNED:	return "Source address is not aligned to PAGE_SIZE, or the length is not dividible by PAGE_SIZE.";
		case -NO_PA:	return "Dest page is not present in memory.";
		case -CANNOT_READ_FROM:	return "Source address is unable to read.";
	}
	return "BUG in user space program errormsg().";
}

int minlen(unsigned long long value)
{
	if(value >= 0x100000000)
		return 8;
	if(value >= 0x10000)
		return 4;
	if(value >= 0x100)
		return 2;
	return 1;
}
